#include "vlckits.h"
#include <QDebug>

#include <QDir>

VLCKits::VLCKits(QObject *parent) : QObject(parent)
{
    initVLC();
}

VLCKits::~VLCKits() {
    libvlc_media_player_release(_pMediaPlayer);
    libvlc_media_release(_pMedia);
    libvlc_release(_pInstance);
}

static void processPosition(VLCKits * pkits)
{
    //百分比
    float pos = libvlc_media_player_get_position(pkits->mediaPlayer());
    pkits->setTimeSliderPos(pos * 100);

    const vector<libvlc_time_t> & durationThis = pkits->durationArr();
    libvlc_time_t totalSecs = durationThis[pkits->currentIndex()];
    qDebug() << "total secs: " << totalSecs;
    libvlc_time_t curSecs = libvlc_media_player_get_time(pkits->mediaPlayer()) / 1000;
    qDebug() << "cur secs: " << curSecs;
    pkits->setCurPlayTime(curSecs);
    pkits->setTotalTime(totalSecs);
}

static void processVolume(VLCKits * pkits)
{
    int val = libvlc_audio_get_volume(pkits->mediaPlayer());
    qDebug() << ">>> volume:" << val;
    if(val == -1) {
        return;
    }
    pkits->setVolumePos(val);
}

static void processMediaChanged(VLCKits* pkits)
{
    qDebug() << ">>>>> processMediaChanged()";
    pkits->addMediaIndex();
}

static void vlc_callback( const struct libvlc_event_t *p_event, void *p_data )
{
    VLCKits * pkits = static_cast<VLCKits*>(p_data);
    if(pkits) {
        switch(p_event->type) {
        case libvlc_MediaPlayerPositionChanged://播放位置变化时
            processPosition(pkits); break;
        case libvlc_MediaPlayerAudioVolume://音量变化时
            processVolume(pkits); break;
        case libvlc_MediaPlayerMediaChanged://播放的媒体变化时
            processMediaChanged(pkits); break;
        }
    }
}

bool VLCKits::initVLC()
{
    _pInstance = libvlc_new(0, nullptr);
    if(_pInstance) {
        _pMediaPlayer = libvlc_media_player_new(_pInstance);
        if(_pMediaPlayer) {
            _pEventManager = libvlc_media_player_event_manager(_pMediaPlayer);
            if(_pEventManager) {
                //注册媒体播放器的事件处理器
                //1. 位置发生改变时
                libvlc_event_attach(_pEventManager, libvlc_MediaPlayerPositionChanged,
                                    vlc_callback, this);
                //2. 声音变化时
                libvlc_event_attach(_pEventManager, libvlc_MediaPlayerAudioVolume,
                                    vlc_callback, this);
                //3. 媒体改变时(添加的代码)
                libvlc_event_attach(_pEventManager, libvlc_MediaPlayerMediaChanged,
                                    vlc_callback, this);
                return true;
            } else {
                libvlc_media_player_release(_pMediaPlayer);
                libvlc_release(_pInstance);
                return false;
            }
        } else {
            libvlc_release(_pInstance);
            return false;
        }
    } else {
        return false;
    }
}

bool VLCKits::addlist(const QString &filename)
{
    //设置列表播放器
    if(!_pMediaListPlayer){
        _pMediaListPlayer = libvlc_media_list_player_new(_pInstance);
        if(!_pMediaListPlayer) {
            return false;
        }
    }

    if(!_pMediaList){
        _pMediaList = libvlc_media_list_new(_pInstance);
        if(!_pMediaList) {
            return false;
        }
    }

    QString filenameNow = QDir::toNativeSeparators(filename);
    _pMedia = libvlc_media_new_path(_pInstance, filenameNow.toStdString().c_str());
    if(!_pMedia) {
        return false;
    }
    //将媒体添加到播放列表中
    libvlc_media_list_add_media(_pMediaList, _pMedia);
    //解析媒体元数据
    libvlc_media_parse(_pMedia);
    libvlc_time_t durationSecs = libvlc_media_get_duration(_pMedia) / 1000;
    _durationArr.push_back(durationSecs);
    libvlc_media_release(_pMedia);

    //列表播放器关联媒体列表
    libvlc_media_list_player_set_media_list(_pMediaListPlayer, _pMediaList);
    //设置播放模式：列表循环播放
    libvlc_media_list_player_set_playback_mode(_pMediaListPlayer, libvlc_playback_mode_loop);
    //媒体列表播放器关联媒体播放器(必须加)
    libvlc_media_list_player_set_media_player(_pMediaListPlayer, _pMediaPlayer);

    return true;
}

bool VLCKits::play(int index, void *hwnd)
{
    _currentIndex = index;
    _currentIndex--;
    libvlc_media_player_set_hwnd(_pMediaPlayer, hwnd);//设置播放窗口
    libvlc_media_list_player_play_item_at_index(_pMediaListPlayer, index);

    return true;
}

void VLCKits::addMediaIndex() {
    ++_currentIndex;
    _currentIndex %= _durationArr.size();


    updateCurrentFileShow(_currentIndex);

    qDebug() << "addMediaIndex" << "currentIndex : " << _currentIndex;

}

void VLCKits::play()
{
    libvlc_state_t state = libvlc_media_player_get_state(_pMediaPlayer);
    if(state == libvlc_Paused ||
        state == libvlc_Stopped) {
        libvlc_media_player_play(_pMediaPlayer);
    }
}

void VLCKits::pause()
{
    libvlc_state_t state = libvlc_media_player_get_state(_pMediaPlayer);
    if(state == libvlc_Playing) {
        libvlc_media_player_pause(_pMediaPlayer);
    }
}

void VLCKits::stop()
{
    libvlc_state_t state = libvlc_media_player_get_state(_pMediaPlayer);
    if(state == libvlc_Playing ||
        state == libvlc_Paused) {
        libvlc_media_player_stop(_pMediaPlayer);
        //重置进度条的位置
        emit sigTimeSliderPos(0);
    }
}

void VLCKits::setTimeSliderPos(int value)
{   //发送信号
    emit sigTimeSliderPos(value);
}

void VLCKits::setCurPlayTime(const qint64 & curMs)
{   //发送信号
    emit sigCurPlay(curMs);
}

void VLCKits::setTotalTime(const qint64 &tatalMs)
{   //发送信号
    emit sigTotal(tatalMs);
}

void VLCKits::setVolumePos(int value)
{
    emit sigVolumeSliderPos(value);
}

void VLCKits::setVolume(int value)
{
    //qDebug() << "199----------" << endl;
    libvlc_audio_set_volume(_pMediaPlayer, value);
}

void VLCKits::setPosition(int value)
{
    libvlc_media_player_set_position(_pMediaPlayer, value / 100.0);
}
